package cn.buk.qms.service;

import cn.buk.common.Constant;
import cn.buk.common.JsonResult;
import cn.buk.common.dto.eterm.PnrDto;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.tms.dao.PnrDao;
import cn.buk.tms.dto.PnrSummary;
import cn.buk.tms.entity.misc.EntDepartment;
import cn.buk.tms.entity.misc.FareCondition;
import cn.buk.tms.entity.misc.Pnr;
import cn.buk.tms.entity.misc.PnrAlert;
import cn.buk.tms.entity.misc.PnrLog;
import cn.buk.tms.entity.misc.PnrMobile;
import cn.buk.tms.entity.misc.PnrUsed;
import cn.buk.common.util.DateUtil;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PnrServiceImpl extends BaseAbstractService implements PnrService {

  private final static Logger logger = LogManager.getLogger(PnrServiceImpl.class);

  @Autowired
  private PnrDao pnrDao;

  @Override
  public int getPnrStatusCount(String pnrStatus, String etermUsername, int enterpriseId) {
    return pnrDao.getPnrStatusCount(pnrStatus, etermUsername, enterpriseId);
  }


  @Override
  public List<PnrLog> searchPnrLog(int enterpriseId, CommonSearchCriteria sc) {
    return pnrDao.searchPnrLog(enterpriseId, sc);
  }

  @Override
  public int savePnrLog(int enterpriseId, String pnrNo, String pnrDetail, String remark) {
    return pnrDao.savePnrLog(enterpriseId, pnrNo, pnrDetail, remark);
  }

  @Override
  public List<FareCondition> searchFareConditions(int enterpriseId, CommonSearchCriteria sc) {
    return pnrDao.searchFareConditions(enterpriseId, sc);
  }

  @Override
  public List<PnrAlert> searchPnrAlert(int enterpriseId, int alertType, CommonSearchCriteria sc) {
    return pnrDao.searchPnrAlert(enterpriseId, alertType, sc);
  }

  /**
   * 删除状态为XX的编码，也就是已经被取消的编码，系统不再进行管理
   */
  @Override
  public void deletePnrXX() {
    List<Pnr> pnrs = pnrDao.searchPnrXX();
    for (Pnr pnr : pnrs) {
      if (!Pnr.testOfficeNoFormat(pnr.getBookOfficeNo())) {
        //officeNo格式不正确
        logger.warn("office no is wrong: " + pnr.getBookOfficeNo() + ", " + pnr.getId());
        continue;
      }

      PnrLog log = new PnrLog();
      log.setEnterpriseId(pnr.getEnterpriseId());
      log.setPnrNo(pnr.getPnrNo());
      log.setPnrDetail(pnr.getPnrDetail());
      log.setRemark("AUTO DELETE FOR XX.");

      if (pnrDao.delete(pnr.getId(), log) < 1) {
        logger.info("delete xx pnr failed.");
        break;
      }
    }
  }

  @Override
  public List<PnrUsed> searchPnrUsed(CommonSearchCriteria sc, int enterpriseId) {
    return pnrDao.searchPnrUsed(enterpriseId, sc);
  }

  @Override
  public JsonResult savePnrMonitor(int enterpriseId, String pnr, int monitorType) {
    if (pnr == null || pnr.trim().length() < 5 || pnr.trim().length() > 6) {
      return JsonResult.createJsonResult(-1, "编码长度不符合要求");
    }

    int retCode = pnrDao.savePnrMonitor(enterpriseId, pnr, monitorType);
    return JsonResult.createJsonResult(retCode);
  }

  /**
   * 分析编码
   */
  @Override
  public JsonResult analyzeUsedPnr(final int enterpriseId) {
    CommonSearchCriteria sc = new CommonSearchCriteria();
    final int pageSize = 10000;
    int pageNo = 0;
    sc.setPageSize(pageSize);


    doSendAlert(enterpriseId, "重新开始分析编码: NS 2018-11-9", null, EntDepartment.DEPT_ADMINISTRATOR);

    String carrier, ddate;
    Set<String> pnrSet = new HashSet<>();
    int total = 0;

    while (true) {
      pageNo++;
      sc.setPageNo(pageNo);

      List<Pnr> pnr0s = pnrDao.search(enterpriseId, sc);

      boolean b = pnr0s.size() == pageSize;

      for (Pnr pnr : pnr0s) {
        if (!pnr.getPnrDetail().contains(pnr.getPnrNo())) {
          continue;
        }
        try {
          PnrDto dto = new PnrDto();
          dto.setPnrDetail(pnr.getPnrDetail());

          if (dto.getFlightNo() == null) {
            continue;
          }

          carrier = dto.getFlightNo().substring(0, 2);
          ddate = DateUtil.formatDate(dto.getDdate(), "yyyy-MM-dd");
          if ("NS".equalsIgnoreCase(carrier) && "2018-11-09".equalsIgnoreCase(ddate)) {
            if (pnrSet.add(dto.getPnrNo())) {
              logger.info(dto.getPnrNo() + ": " + dto.getEtermUsername() + ", " + pnr.getId() + ", " + pnr.getCreateTime());
              total += dto.getPsgCount();
              logger.info("total: " + total);
              doSendAlert(enterpriseId, "编码: " + dto.getPnrNo() + ", 用户名：" + dto.getEtermUsername() + ", 内容：" + dto.getCompactPnrDetail(), null, EntDepartment.DEPT_ADMINISTRATOR);
            }
          }
        } catch (Exception ex) {
          logger.info(pnr.getPnrNo() + ", " + pnr.getId() + ": (exception)" + ex.getMessage());
          ex.printStackTrace();
        }

      }

      if (!b) {
        break;
      }
    }


    pageNo = 0;
    while (true) {
      pageNo++;
      sc.setPageNo(pageNo);

      List<PnrUsed> pnrs = pnrDao.searchPnrUsed(enterpriseId, sc);

      boolean b = pnrs.size() == pageSize;

      for (PnrUsed pnr : pnrs) {
        if (!pnr.getPnrDetail().contains(pnr.getPnrNo())) {
          continue;
        }
        try {
          PnrDto dto = new PnrDto();
          dto.setPnrDetail(pnr.getPnrDetail());

          if (dto.getFlightNo() == null) {
            continue;
          }

          carrier = dto.getFlightNo().substring(0, 2);
          ddate = DateUtil.formatDate(dto.getDdate(), "yyyy-MM-dd");
          if ("NS".equalsIgnoreCase(carrier) && "2018-11-09".equalsIgnoreCase(ddate)) {
            if (pnrSet.add(dto.getPnrNo())) {
              logger.info(dto.getPnrNo() + ": " + dto.getEtermUsername() + ", " + pnr.getId() + ", " + pnr.getCreateTime() + "(PnrUsed)");
              total += dto.getPsgCount();
              logger.info("total: " + total);
              doSendAlert(enterpriseId, "编码: " + dto.getPnrNo() + ", 用户名：" + dto.getEtermUsername() + ", 内容：" + dto.getCompactPnrDetail(), null, EntDepartment.DEPT_ADMINISTRATOR);
            }
          }
        } catch (Exception ex) {
          logger.info(pnr.getPnrNo() + ", " + pnr.getId() + ": (exception)" + ex.getMessage());
          ex.printStackTrace();
        }

      }

      if (!b) {
        break;
      }
    }

    doSendAlert(enterpriseId, "占位总数：" + total, null, EntDepartment.DEPT_ADMINISTRATOR);


    return JsonResult.createJsonResult(1);
  }

  @Override
  public List<PnrSummary> statPnrByUsername(int enterpriseId, CommonSearchCriteria sc) {
    return pnrDao.statPnrByUsername(enterpriseId, sc);
  }

  @Override
  public List<Pnr> searchPnrCtcm(int enterpriseId, String carrier, String etermUsername, CommonSearchCriteria sc) {
    return pnrDao.searchPnrCtcm(enterpriseId, carrier, etermUsername, 60, null, sc);
  }

  @Override
  public List<Pnr> searchPnrCtct(int enterpriseId, CommonSearchCriteria sc) {
    return pnrDao.searchPnrCtct(enterpriseId, sc);
  }

  @Override
  public List<PnrMobile> searchPnrMobile(int enterpriseId, CommonSearchCriteria sc) {
    return pnrDao.searchPnrMobile(enterpriseId, sc);
  }

  @Override
  public JsonResult createPnrMobile(int enterpriseId, String mobile) {
    JsonResult jsonResult = new JsonResult();

    String regEx = "([1][0-9]{10,})+";
    if (Pattern.compile(regEx).matcher(mobile).find()) {
      int status = pnrDao.createPnrMobile(enterpriseId, mobile);

      if (status > 0) {
        jsonResult.setStatus("OK");
      } else {
        jsonResult.setStatus("ER");
        jsonResult.setErrcode(status);
        jsonResult.setErrmsg("保存失败");
      }

    } else {
      jsonResult.setStatus("ER");
      jsonResult.setErrmsg("请检查手机号格式");
    }


    return jsonResult;
  }

  @Override
  public JsonResult deletePnrMobile(int enterpriseId, int id) {
    JsonResult jsonResult = new JsonResult();

    int status = pnrDao.deletePnrMobile(enterpriseId, id);

    if (status > 0) {
      jsonResult.setStatus("OK");
    } else {
      jsonResult.setStatus("ER");
      jsonResult.setErrcode(status);
    }

    return jsonResult;
  }

  /**
   * 查找PNR
   */
  @Override
  public List<Pnr> searchPnr(int enterpriseId, CommonSearchCriteria sc) {
    return pnrDao.search(enterpriseId, sc);
  }

  @Override
  public List<Pnr> searchPnr(int enterpriseId, String segStatus, int segCount) {
    return pnrDao.search(enterpriseId, segStatus, segCount);
  }

  /**
   * pnr的checktime超过24小时的
   */
  @Override
  public List<Pnr> searchPnrCheckTimeMoreThan24Hours(int enterpriseId, int max) {
    return pnrDao.searchCheckTimeMoreThan24Hours(enterpriseId, max);
  }


  @Override
  public Pnr getPnrById(int id, int enterpriseId) {
    Pnr pnr = pnrDao.getPnrById(id);
    if (pnr != null && pnr.getEnterpriseId() == enterpriseId) {
      return pnr;
    } else {
      return null;
    }
  }


  @Override
  public int delete(final int id, final int enterpriseId, final int userId) {
    Pnr pnr = getPnrById(id, enterpriseId);
    if (pnr != null && pnr.getEnterpriseId() == enterpriseId) {
      if (Constant.PNR_STATUS_HK.equalsIgnoreCase(pnr.getSegStatus())) {
        return pnrDao.delete(id, enterpriseId, userId);
      } else {
        return pnrDao.deleteInvalidPnr(enterpriseId, pnr.getDdate(), pnr.getFlightNo(), pnr.getSubclass(), pnr.getPnrNo(), userId);
      }
    } else {
      return 0;
    }
  }

}
